#!/bin/bash
root_dir="/usr/local/edh"
script_path=$(readlink -f "${BASH_SOURCE[0]}")
script_dir=$(dirname "$script_path")
source ~/.bashrc
source /etc/profile
role=$1
MODE_FILE="$script_dir/mode"
mode=$(cat $MODE_FILE)
function start_namenode(){
  if [ $mode == "ha" ];then
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking zookeeper cluster..."
    env_file="$script_dir/config.env"
    while IFS= read -r line
    do
      if [[ $line == *"ha.zookeeper.quorum"* ]];then
        IFS="=" read -r name value <<< $line
        IFS="," read -r -a zk_cluster <<< $value
        for zk_node in "${zk_cluster[@]}";do
          IFS=":" read -r ip port <<< $zk_node
          wait_for_service zk_node $ip $port
        done
      fi
    done < "$env_file"
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking $root_dir/hadoop/hdfs/journal..."
    if [ -z "$(ls -A $root_dir/hadoop/hdfs/journal)" ];then
      echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING $root_dir/hadoop/hdfs/journal is empty,formatting..."
      echo "Y" | hdfs namenode -format
      if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO formatting namenode success"
      else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR formatting namenode fail"
      fi
    else
      echo "$(date +"%Y-%m-%d %H:%M:%S") INFO $root_dir/hadoop/hdfs/journal is not empty"
    fi
    ha_service_state=$(hdfs haadmin -getAllServiceState)
    if [[ $ha_service_state == *"active"* ]] || [[  $ha_service_state == *"standby"*  ]];then
      echo "$(date +"%Y-%m-%d %H:%M:%S") INFO an namenode exist,initialize metadata for another namenode"
      hdfs namenode -bootstrapStandby
      if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO bootstrapping metadata success"
      else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR bootstrapping metadata fail"
      fi
    fi
  fi

  if [ $mode == "sa" ];then
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking $root_dir/hadoop/hdfs/name..."
    if [ -z "$(ls -A $root_dir/hadoop/hdfs/name)" ];then
      echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING namenode name dir is empty,formatting..."
      echo "Y" | hdfs namenode -format
      if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO formatting namenode success"
      else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR formatting namenode fail"
      fi
    else
      echo "$(date +"%Y-%m-%d %H:%M:%S") INFO $root_dir/hadoop/hdfs/name is not empty"
    fi
  fi
  hdfs --daemon start namenode
  if [ $? -eq 0 ];then
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting namenode success"
  else
    echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting namenode fail"
  fi
}

function start_secondarynamenode(){
  if [ $mode == "ha" ];then
    echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR secondarynamenode only run in sa mode"
    return
  else
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking namenode..."
    while IFS= read -r line
    do
      if [[ $line == *"dfs.namenode.http-address"* ]];then
        IFS="=" read -r prefix suffix <<< $line
        IFS=":" read -r ip port <<< $suffix
        wait_for_service namenode $ip $port
      fi
    done < "$env_file"
    hdfs --daemon start secondarynamenode
    if [ $? -eq 0 ];then
      echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting secondarynamenode success"
    else
      echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting secondarynamenode fail"
    fi
  fi
}

function start_resourcemanager(){
  if [ $mode == "ha" ];then
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking zookeeper cluster"
    env_file="$script_dir/config.env"
    while IFS= read -r line
    do
      if [[ $line == *"hadoop.zk.address"* ]];then
        IFS="=" read -r prefix suffix <<< $line
        IFS="," read -r -a zk_cluster <<< $suffix
        for zk_node in "${zk_cluster[@]}";do
          IFS=":" read -r ip port <<< $zk_node
          wait_for_service zk_node $ip $port
        done
      fi
    done < "$env_file"
  fi
  yarn --daemon start resourcemanager
  if [ $? -eq 0 ];then
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting resourcemanager success"
  else
    echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting resourcemanager fail"
  fi
}

function start_nodemanager(){
  echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking resourcemanager..."
  env_file="$script_dir/config.env"
  while IFS= read -r line
  do
    if [[ $line == *"resource-tracker.address"* ]];then
      IFS="=" read -r prefix rm_node <<< $line
      IFS=":" read -r ip port <<< $rm_node
      wait_for_service resourcemanager $ip $port
    fi
  done < "$env_file"
  yarn --daemon start nodemanager
  if [ $? -eq 0 ];then
    echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting nodemanager success"
  else
    echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting nodemanager fail"
  fi
}

function start_datanode(){
  echo "$(date +"%Y-%m-%d %H:%M:%S") INFO checking namenode..."
  if [ $mode == "sa" ];then
    env_file="$script_dir/config.env"
    while IFS= read -r line
    do
      if [[ $line == *"dfs.namenode.http-address"* ]];then
          IFS="=" read -r prefix suffix <<< $line
          IFS=":" read -r ip port <<< $suffix
          wait_for_service namenode $ip $port
      fi
    done < "$env_file"
    hdfs --daemon start datanode
    if [ $? -eq 0 ];then
      echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting datanode success"
    else
      echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting datanode fail"
    fi
  fi
  if [ $mode == "ha" ];then
    ha_service_state=$(hdfs haadmin -getAllServiceState)
    if [[ $ha_service_state == *"active"* ]];then
      hdfs --daemon start datanode
      if [ $? -eq 0 ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") INFO starting datanode success"
      else
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR starting datanode fail"
      fi
    else
      echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR no active namenode is available,starting datanode fail"
    fi
  fi

}

function wait_for_service(){
  service=$1
  ip=$2
  port=$3
  max_retry=5
  retry_second=5
  let i=1
  nc -z $ip $port
  result=$?
  while [ $result -ne 0 ]; do
    echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING [$i/$max_retry] $service $ip:$port is not available"
    if [ $i == $max_retry ];then
        echo "$(date +"%Y-%m-%d %H:%M:%S") ERROR [$i/$max_retry] $service $ip:$port is still not available,quitting..."
        return
    fi
    echo "$(date +"%Y-%m-%d %H:%M:%S") WARNING [$i/$max_retry] reconnecting $service $ip:$port in $retry_second seconds"
    let "i++"
    sleep $retry_second
    nc -z $ip $port
    result=$?
  done
  echo "$(date +"%Y-%m-%d %H:%M:%S") INFO [$i/$max_retry] $service $ip:$port is available"
}
#wait_for_service namenode bigdata01 9870

if [ $role == "namenode" ];then
  start_namenode
fi
if [ $role == "secondarynamenode" ];then
  start_secondarynamenode
fi
if [ $role == "resourcemanager" ];then
  start_resourcemanager
fi
if [ $role == "nodemanager" ];then
  start_nodemanager
fi
if [ $role == "datanode" ];then
  start_datanode
fi
